Technical Q&A QA1070
Loading Scripting Additions without initializing AppleScript in Mac OS X


Q: I would like to send Apple events to a number of Carbonized scripting additions in my Mac OS X application, but my application does not call AppleScript. How can I load the Scripting Additions in my application without initializing AppleScript?

A: While it's true that scripting additions are loaded in to your application's system dispatch table when AppleScript is initialized, it is not necessary to initialize AppleScript in order to load the Scripting Additions into your application's system dispatch table. The following discusses the necessary calls you need to make to install the Scripting Additions.

First, a little architectural background: In classic Mac OS, scripting addition handlers are loaded at boot time into a shared system-wide table (the Apple Event Manager's "system handler table"). Also, the scripting addition handlers are refreshed whenever someone sends a kASAppleScriptSuite/kGetAEUT Event to the handler installed by AppleScript ("GDUT" is short for "get dynamic user terminology."). AppleScript sends itself a kASAppleScriptSuite/kGetAEUT event when it is first initialized and before it compiles a script.

In Mac OS X, the system handler table isn't shared by all applications and there is a separate one created for each application, so each application's system handler table must be initialized separately. For performance reasons, this isn't done automatically as a normal part of the application initialization sequence - it is only done if an application uses AppleScript or initializes the table itself.

Of course, the simplest way to refresh the scripting addition entries in the system Apple event dispatch table is to open a connection to the AppleScript component (as shown in Listing 1). In turn, this will load the scripting additions in the scripting additions folder and refresh the entries in the system Apple event dispatch table.



        /* open the scripting component */
    theComponent = OpenDefaultComponent(kOSAComponentType,
                                    typeAppleScript);

Listing 1. Opening a connection to the AppleScript component.



However, if your application is only interested in using the scripting additions, then initializing all of AppleScript may entail additional overhead that may not be warranted. So, if you would like to load the scripting additions into your application's system dispatch table without loading AppleScript, you can do so by performing two steps:

  1. Make sure the kASAppleScriptSuite/kGetAEUT Apple event handler is installed. This can be done by calling the OSAInstallStandardHandlers routine in the com.apple.openscripting framework.

  2. Once the kASAppleScriptSuite/kGetAEUT Apple event handler is installed in your application's Apple event dispatch table, your application should send an kASAppleScriptSuite/kGetAEUT Apple event to itself that will refresh the scripting addition entries in the system dispatch table.

Listing 2 shows the source code required to perform these two steps. A potentially useful side effect of this routine is that every time it is called, it will synchronize the set of loaded scripting additions in your application's system Apple event dispatch table with the contents of the scripting additions folder.



void EnableScriptingAdditions() {
    OSErr err;
    AppleEvent e, r;
    ProcessSerialNumber selfPSN = { 0, kCurrentProcess };
    void (*f)();
    CFBundleRef b;

        /* First, call the routine that installs the
        kASAppleScriptSuite / kGetAEUTApple event handler
        in your applications Apple event dispatch table.
        This part is only required if your application
        is running in Mac OS X.  It will it will silently
        fail anywhere else (such as when running in classic or Mac OS 9). */
    b = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.openscripting"));
    if (b != NULL) {
        f = (void (*)()) CFBundleGetFunctionPointerForName(b,
                              CFSTR("OSAInstallStandardHandlers"));
        if (f != NULL) (*f)();
    }

        /* Second, call the kASAppleScriptSuite / kGetAEUTApple Apple
        event handler that we just installed.  This step will load
        the scripting additions into our application's system
        Apple event dispatch table - it will also refresh the table
        so it is synchronized with the contents of the scripting
        additions folder. */
    err = AEBuildAppleEvent(kASAppleScriptSuite, kGetAEUT,
        typeProcessSerialNumber, &selfPSN, sizeof(selfPSN),
        kAutoGenerateReturnID, kAnyTransactionID, &e, NULL, "");
    if (err == noErr) {
        AESend(&e, &r, kAEWaitReply, kAENormalPriority,
               kAEDefaultTimeout, NULL, NULL);
        AEDisposeDesc(&e);
        AEDisposeDesc(&r);
    }
}

Listing 2. Sample routine for loading scripting additions.




[Sep 13 2001]


Developer Documentation | Technical Notes | Development Kits | Sample Code